package com.lineage.server.model;

import com.lineage.server.datatables.MobSkillTable;
import com.lineage.server.datatables.SkillsTable;
import com.lineage.server.model.Instance.L1ItemInstance;
import com.lineage.server.model.Instance.L1NpcInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.skill.L1SkillDelayforMob;
import com.lineage.server.model.skill.L1SkillUse;
import com.lineage.server.serverpackets.S_DoActionGFX;
import com.lineage.server.serverpackets.S_PacketBoxWindShackle;
import com.lineage.server.serverpackets.S_Paralysis;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.S_SkillSound;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1MobSkill;
import com.lineage.server.templates.L1Skills;
import com.lineage.server.utils.L1SpawnUtil;
import com.lineage.server.utils.RandomArrayList;
import com.lineage.server.world.World;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1MobSkillUse {
  private static final Log _log = LogFactory.getLog(L1MobSkillUse.class);
  
  private static final Random _rnd = new Random();
  
  private L1MobSkill _mobSkillTemplate = null;
  
  private L1NpcInstance _attacker = null;
  
  private L1Character _target = null;
  
  private int _sleepTime = 0;
  
  private int[] _skillUseCount;
  
  private int _skillSize;
  
  public L1MobSkillUse(L1NpcInstance npc) {
    try {
      this._sleepTime = 0;
      this._mobSkillTemplate = MobSkillTable.getInstance().getTemplate(npc.getNpcTemplate().get_npcId());
      if (this._mobSkillTemplate == null)
        return; 
      this._attacker = npc;
      this._skillSize = getMobSkillTemplate().getSkillSize();
      this._skillUseCount = new int[this._skillSize];
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  private int getSkillUseCount(int idx) {
    return this._skillUseCount[idx];
  }
  
  private void skillUseCountUp(int idx) {
    int[] skillUseCount = this._skillUseCount;
    skillUseCount[idx] = skillUseCount[idx] + 1;
  }
  
  public void resetAllSkillUseCount() {
    if (this._mobSkillTemplate == null)
      return; 
    int i = 0;
    while (i < this._skillSize) {
      this._skillUseCount[i] = 0;
      i++;
    } 
  }
  
  public int getSleepTime() {
    return this._sleepTime;
  }
  
  public void setSleepTime(int i) {
    this._sleepTime = i;
  }
  
  public L1MobSkill getMobSkillTemplate() {
    return this._mobSkillTemplate;
  }
  
  public boolean isSkillTrigger(L1Character tg) {
    if (this._mobSkillTemplate == null)
      return false; 
    this._target = tg;
    int type = getMobSkillTemplate().getType(0);
    if (type == 0)
      return false; 
    int i = 0;
    while (i < getMobSkillTemplate().getSkillSize() && getMobSkillTemplate().getType(i) != 0) {
      if (isSkillUseble(i, false))
        return true; 
      i++;
    } 
    return false;
  }
  
  public final boolean skillUse(L1Character tg, boolean isTriRnd) {
    if (this._mobSkillTemplate == null)
      return false; 
    int type = this._mobSkillTemplate.getType(0);
    if (type == 0)
      return false; 
    int[] skills = null;
    int skillSizeCounter = 0;
    int skillSize = this._mobSkillTemplate.getSkillSize();
    if (skillSize >= 0)
      skills = new int[skillSize]; 
    int i = 0;
    i = 0;
    while (i < getMobSkillTemplate().getSkillSize() && getMobSkillTemplate().getType(i) != 0) {
      int changeType = getMobSkillTemplate().getChangeTarget(i);
      if (changeType > 0) {
        this._target = changeTarget(changeType, i);
      } else {
        this._target = tg;
      } 
      if (isSkillUseble(i, isTriRnd)) {
        skills[skillSizeCounter] = i;
        skillSizeCounter++;
      } 
      i++;
    } 
    if (skillSizeCounter != 0) {
      int actNo = skills[_rnd.nextInt(skillSizeCounter)];
      int changeType2 = this._mobSkillTemplate.getChangeTarget(actNo);
      if (changeType2 > 0) {
        this._target = changeTarget(changeType2, i);
      } else {
        this._target = tg;
      } 
      if (useSkill(actNo))
        return true; 
    } 
    return false;
  }
  
  private void setDelay(int idx) {
    if (this._mobSkillTemplate.getReuseDelay(idx) > 0)
      L1SkillDelayforMob.onSkillUse(this._attacker, this._mobSkillTemplate.getReuseDelay(idx), idx); 
  }
  
  private boolean useSkill(int idx) {
    boolean isUseSkill = false;
    int type = getMobSkillTemplate().getType(idx);
    switch (type) {
      case 1:
        if (physicalAttack(idx)) {
          skillUseCountUp(idx);
          isUseSkill = true;
        } 
        break;
      case 2:
        if (magicAttack(idx)) {
          skillUseCountUp(idx);
          isUseSkill = true;
        } 
        break;
      case 3:
        if (summon(idx)) {
          skillUseCountUp(idx);
          isUseSkill = true;
        } 
        break;
      case 4:
        if (poly(idx)) {
          skillUseCountUp(idx);
          isUseSkill = true;
        } 
        break;
      case 5:
        if (areashock_stun(idx)) {
          skillUseCountUp(idx);
          setDelay(idx);
          isUseSkill = true;
        } 
        break;
      case 6:
        if (areacancellation(idx)) {
          skillUseCountUp(idx);
          setDelay(idx);
          isUseSkill = true;
        } 
        break;
      case 7:
        if (weapon_break(idx)) {
          skillUseCountUp(idx);
          setDelay(idx);
          isUseSkill = true;
        } 
        break;
      case 8:
        if (potionturntodmg(idx)) {
          skillUseCountUp(idx);
          setDelay(idx);
          isUseSkill = true;
        } 
        break;
      case 9:
        if (pollutewaterwave(idx)) {
          skillUseCountUp(idx);
          setDelay(idx);
          isUseSkill = true;
        } 
        break;
      case 10:
        if (healturntodmg(idx)) {
          skillUseCountUp(idx);
          setDelay(idx);
          isUseSkill = true;
        } 
        break;
      case 11:
        if (areasilence(idx)) {
          skillUseCountUp(idx);
          setDelay(idx);
          isUseSkill = true;
        } 
        break;
      case 12:
        if (areadecaypotion(idx)) {
          skillUseCountUp(idx);
          setDelay(idx);
          isUseSkill = true;
        } 
        break;
      case 13:
        if (areawindshackle(idx)) {
          skillUseCountUp(idx);
          setDelay(idx);
          isUseSkill = true;
        } 
        break;
      case 14:
        if (areadebuff(idx)) {
          skillUseCountUp(idx);
          setDelay(idx);
          isUseSkill = true;
        } 
        break;
      case 15:
        if (area_poison(idx)) {
          skillUseCountUp(idx);
          setDelay(idx);
          isUseSkill = true;
        } 
        break;
    } 
    return isUseSkill;
  }
  
  private boolean area_poison(int idx) {
    if (this._attacker.getMapId() == 93)
      return false; 
    int actId = getMobSkillTemplate().getActid(idx);
    int actionid = 1;
    if (actId > 0)
      actionid = actId; 
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)this._attacker).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      if (!pc.isGmInvis())
        L1SpawnUtil.spawnEffect(86125, 3, pc.getX(), pc.getY(), this._attacker.getMapId(), (L1Character)this._attacker, 0); 
    } 
    S_DoActionGFX gfx = new S_DoActionGFX(this._attacker.getId(), actionid);
    this._attacker.broadcastPacketAll((ServerBasePacket)gfx);
    this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
    return true;
  }
  
  private boolean areadebuff(int idx) {
    if (this._attacker.getMapId() == 93)
      return false; 
    int skillid = getMobSkillTemplate().getSkillId(idx);
    int actId = getMobSkillTemplate().getActid(idx);
    int gfxId = getMobSkillTemplate().getGfxid(idx);
    int time = getMobSkillTemplate().getLeverage(idx);
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)this._attacker).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      if (skillid == 71 && pc.hasSkillEffect(4011))
        continue; 
      L1SkillUse skillUse = new L1SkillUse();
      boolean canUseSkill = false;
      if (skillid > 0)
        canUseSkill = skillUse.checkUseSkill(null, skillid, pc.getId(), pc.getX(), pc.getY(), time, 4, 
            (L1Character)this._attacker, actId, gfxId); 
      if (!canUseSkill || pc.hasSkillEffect(skillid))
        continue; 
      skillUse.handleCommands(null, skillid, pc.getId(), pc.getX(), pc.getY(), time, 4, (L1Character)this._attacker);
    } 
    int actionid = 19;
    if (actId > 0)
      actionid = actId; 
    this._attacker.broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(this._attacker.getId(), actionid));
    this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
    return true;
  }
  
  private boolean areawindshackle(int idx) {
    if (this._attacker.getMapId() == 93)
      return false; 
    int actId = getMobSkillTemplate().getActid(idx);
    int actionid = 19;
    if (actId > 0)
      actionid = actId; 
    int gfxId = getMobSkillTemplate().getGfxid(idx);
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)this._attacker).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      if (!pc.hasSkillEffect(167)) {
        pc.sendPacketsAll((ServerBasePacket)new S_SkillSound(pc.getId(), gfxId));
        pc.sendPackets((ServerBasePacket)new S_PacketBoxWindShackle(pc.getId(), 16));
        pc.setSkillEffect(167, 16000);
      } 
    } 
    S_DoActionGFX gfx = new S_DoActionGFX(this._attacker.getId(), actionid);
    this._attacker.broadcastPacketAll((ServerBasePacket)gfx);
    this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
    return true;
  }
  
  private boolean areadecaypotion(int idx) {
    if (this._attacker.getMapId() == 93)
      return false; 
    int actId = getMobSkillTemplate().getActid(idx);
    int actionid = 19;
    if (actId > 0)
      actionid = actId; 
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)this._attacker).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      if (!pc.hasSkillEffect(71))
        (new L1SkillUse()).handleCommands(pc, 71, pc.getId(), pc.getX(), pc.getY(), 0, 4); 
    } 
    S_DoActionGFX gfx = new S_DoActionGFX(this._attacker.getId(), actionid);
    this._attacker.broadcastPacketAll((ServerBasePacket)gfx);
    this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
    return true;
  }
  
  private boolean areasilence(int idx) {
    if (this._attacker.getMapId() == 93)
      return false; 
    int actId = getMobSkillTemplate().getActid(idx);
    int actionid = 19;
    if (actId > 0)
      actionid = actId; 
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)this._attacker).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      if (!pc.hasSkillEffect(64) && !pc.hasSkillEffect(161)) {
        pc.sendPacketsAll((ServerBasePacket)new S_SkillSound(pc.getId(), 10708));
        pc.setSkillEffect(64, 16000);
      } 
    } 
    S_DoActionGFX gfx = new S_DoActionGFX(this._attacker.getId(), actionid);
    this._attacker.broadcastPacketAll((ServerBasePacket)gfx);
    this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
    return true;
  }
  
  private boolean healturntodmg(int idx) {
    if (this._attacker.getMapId() == 93)
      return false; 
    int actId = getMobSkillTemplate().getActid(idx);
    int actionid = 19;
    if (actId > 0)
      actionid = actId; 
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)this._attacker).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      if (!pc.hasSkillEffect(4011) && !pc.hasSkillEffect(4012) && !pc.hasSkillEffect(4013)) {
        pc.sendPacketsAll((ServerBasePacket)new S_SkillSound(pc.getId(), 7780));
        pc.setSkillEffect(4013, 12000);
      } 
    } 
    S_DoActionGFX gfx = new S_DoActionGFX(this._attacker.getId(), actionid);
    this._attacker.broadcastPacketAll((ServerBasePacket)gfx);
    this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
    return true;
  }
  
  private boolean pollutewaterwave(int idx) {
    if (this._attacker.getMapId() == 93)
      return false; 
    int actId = getMobSkillTemplate().getActid(idx);
    int actionid = 19;
    if (actId > 0)
      actionid = actId; 
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)this._attacker).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      if (!pc.hasSkillEffect(4011) && !pc.hasSkillEffect(4012) && !pc.hasSkillEffect(4013)) {
        pc.sendPacketsAll((ServerBasePacket)new S_SkillSound(pc.getId(), 7782));
        pc.setSkillEffect(4012, 12000);
      } 
    } 
    S_DoActionGFX gfx = new S_DoActionGFX(this._attacker.getId(), actionid);
    this._attacker.broadcastPacketAll((ServerBasePacket)gfx);
    this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
    return true;
  }
  
  private boolean potionturntodmg(int idx) {
    if (this._attacker.getMapId() == 93)
      return false; 
    int actId = getMobSkillTemplate().getActid(idx);
    int actionid = 19;
    if (actId > 0)
      actionid = actId; 
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)this._attacker).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      if (!pc.hasSkillEffect(4011) && !pc.hasSkillEffect(4012) && !pc.hasSkillEffect(4013) && 
        !pc.hasSkillEffect(71)) {
        pc.sendPacketsAll((ServerBasePacket)new S_SkillSound(pc.getId(), 7781));
        pc.setSkillEffect(4011, 12000);
      } 
    } 
    S_DoActionGFX gfx = new S_DoActionGFX(this._attacker.getId(), actionid);
    this._attacker.broadcastPacketAll((ServerBasePacket)gfx);
    this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
    return true;
  }
  
  private boolean weapon_break(int idx) {
    if (this._attacker.getMapId() == 93)
      return false; 
    int actId = getMobSkillTemplate().getActid(idx);
    int actionid = 19;
    if (actId > 0)
      actionid = actId; 
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)this._attacker).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      L1ItemInstance weapon = pc.getWeapon();
      if (weapon != null) {
        int weaponDamage = _rnd.nextInt(this._attacker.getInt() / 3) + 1;
        pc.sendPacketsAll((ServerBasePacket)new S_SkillSound(pc.getId(), 172));
        pc.sendPackets((ServerBasePacket)new S_ServerMessage(268, weapon.getLogName()));
        pc.getInventory().receiveDamage(weapon, weaponDamage);
      } 
    } 
    S_DoActionGFX gfx = new S_DoActionGFX(this._attacker.getId(), actionid);
    this._attacker.broadcastPacketAll((ServerBasePacket)gfx);
    this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
    return true;
  }
  
  private boolean areacancellation(int idx) {
    if (this._attacker.getMapId() == 93)
      return false; 
    int actId = getMobSkillTemplate().getActid(idx);
    int actionid = 19;
    if (actId > 0)
      actionid = actId; 
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)this._attacker).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      (new L1SkillUse()).handleCommands(pc, 44, pc.getId(), pc.getX(), pc.getY(), 0, 4);
    } 
    S_DoActionGFX gfx = new S_DoActionGFX(this._attacker.getId(), actionid);
    this._attacker.broadcastPacketAll((ServerBasePacket)gfx);
    this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
    return true;
  }
  
  private boolean areashock_stun(int idx) {
    if (this._attacker.getMapId() == 93)
      return false; 
    int actId = getMobSkillTemplate().getActid(idx);
    int actionid = 1;
    if (actId > 0)
      actionid = actId; 
    Iterator<L1PcInstance> iterator = World.get().getVisiblePlayer((L1Object)this._attacker).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      Random random = new Random();
      int shock = random.nextInt(4) + 1;
      if (pc.hasSkillEffect(87))
        shock += pc.getSkillEffectTimeSec(87); 
      if (shock > 4)
        shock = 4; 
      if (!pc.isGmInvis()) {
        pc.setSkillEffect(87, shock * 1000);
        pc.sendPackets((ServerBasePacket)new S_Paralysis(5, true));
        L1SpawnUtil.spawnEffect(81162, shock, pc.getX(), pc.getY(), this._attacker.getMapId(), (L1Character)this._attacker, 
            0);
      } 
    } 
    S_DoActionGFX gfx = new S_DoActionGFX(this._attacker.getId(), actionid);
    this._attacker.broadcastPacketAll((ServerBasePacket)gfx);
    this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
    return true;
  }
  
  private boolean summon(int idx) {
    if (this._attacker.getMapId() == 93)
      return false; 
    int actId = getMobSkillTemplate().getActid(idx);
    int actionid = 19;
    if (actId > 0)
      actionid = actId; 
    int summonId = getMobSkillTemplate().getSummon(idx);
    int min = getMobSkillTemplate().getSummonMin(idx);
    int max = getMobSkillTemplate().getSummonMax(idx);
    int count = 0;
    if (summonId == 0)
      return false; 
    count = _rnd.nextInt(max) + min;
    L1MobSkillUseSpawn skillUseSpawn = new L1MobSkillUseSpawn();
    skillUseSpawn.mobspawn((L1Character)this._attacker, this._target, summonId, count);
    this._attacker.broadcastPacketAll((ServerBasePacket)new S_SkillSound(this._attacker.getId(), 761));
    S_DoActionGFX gfx = new S_DoActionGFX(this._attacker.getId(), actionid);
    this._attacker.broadcastPacketAll((ServerBasePacket)gfx);
    this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
    return true;
  }
  
  private boolean poly(int idx) {
    if (this._attacker.getMapId() == 93)
      return false; 
    int polyId = getMobSkillTemplate().getPolyId(idx);
    int actId = getMobSkillTemplate().getActid(idx);
    int actionid = 19;
    if (actId > 0)
      actionid = actId; 
    boolean usePoly = false;
    if (polyId == 0)
      return false; 
    Iterator<L1PcInstance> localIterator = World.get().getVisiblePlayer((L1Object)this._attacker).iterator();
    while (localIterator.hasNext()) {
      L1PcInstance pc = localIterator.next();
      if (!pc.isDead() && !pc.isGhost() && !pc.isGmInvis() && this._attacker.glanceCheck(pc.getX(), pc.getY())) {
        int npcId = this._attacker.getNpcTemplate().get_npcId();
        switch (npcId) {
          case 81082:
            pc.getInventory().takeoffEquip(945);
            break;
        } 
        L1PolyMorph.doPoly((L1Character)pc, polyId, 1800, 4);
        usePoly = true;
      } 
    } 
    if (usePoly) {
      localIterator = World.get().getVisiblePlayer((L1Object)this._attacker).iterator();
      if (localIterator.hasNext()) {
        L1PcInstance pc = localIterator.next();
        pc.sendPacketsAll((ServerBasePacket)new S_SkillSound(pc.getId(), 230));
      } 
      S_DoActionGFX gfx = new S_DoActionGFX(this._attacker.getId(), actionid);
      this._attacker.broadcastPacketAll((ServerBasePacket)gfx);
      this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
    } 
    return usePoly;
  }
  
  private boolean magicAttack(int idx) {
    L1SkillUse skillUse = new L1SkillUse();
    int skillid = getMobSkillTemplate().getSkillId(idx);
    int actId = getMobSkillTemplate().getActid(idx);
    int gfxId = getMobSkillTemplate().getGfxid(idx);
    boolean canUseSkill = false;
    if (skillid > 0)
      canUseSkill = skillUse.checkUseSkill(null, skillid, this._target.getId(), this._target.getX(), 
          this._target.getY(), 0, 0, (L1Character)this._attacker, actId, gfxId); 
    if (canUseSkill) {
      if (getMobSkillTemplate().getLeverage(idx) > 0)
        skillUse.setLeverage(getMobSkillTemplate().getLeverage(idx)); 
      skillUse.handleCommands(null, skillid, this._target.getId(), this._target.getX(), this._target.getX(), 0, 0, 
          (L1Character)this._attacker);
      L1Skills skill = SkillsTable.get().getTemplate(skillid);
      if (skill.getTarget().equals("attack") && skillid != 18) {
        this._sleepTime = this._attacker.getNpcTemplate().getAtkMagicSpeed();
      } else {
        this._sleepTime = this._attacker.getNpcTemplate().getSubMagicSpeed();
      } 
      return true;
    } 
    return false;
  }
  
  private boolean physicalAttack(int idx) {
    Map<Integer, Integer> targetList = new HashMap<>();
    int areaWidth = getMobSkillTemplate().getAreaWidth(idx);
    int areaHeight = getMobSkillTemplate().getAreaHeight(idx);
    int range = getMobSkillTemplate().getRange(idx);
    int actId = getMobSkillTemplate().getActid(idx);
    int gfxId = getMobSkillTemplate().getGfxid(idx);
    if (this._attacker.getLocation().getTileLineDistance(this._target.getLocation()) > range)
      return false; 
    if (!this._attacker.glanceCheck(this._target.getX(), this._target.getY()))
      return false; 
    this._attacker.setHeading(this._attacker.targetDirection(this._target.getX(), this._target.getY()));
    if (areaHeight > 0) {
      ArrayList<L1Object> objs = World.get().getVisibleBoxObjects((L1Object)this._attacker, 
          this._attacker.getHeading(), areaWidth, areaHeight);
      Iterator<L1Object> iterator = objs.iterator();
      while (iterator.hasNext()) {
        L1Object obj = iterator.next();
        if (!(obj instanceof L1Character))
          continue; 
        L1Character cha = (L1Character)obj;
        if (cha.isDead())
          continue; 
        if (cha instanceof L1PcInstance && ((L1PcInstance)cha).isGhost())
          continue; 
        if (!this._attacker.glanceCheck(cha.getX(), cha.getY()))
          continue; 
        if (this._target instanceof L1PcInstance || this._target instanceof com.lineage.server.model.Instance.L1SummonInstance || 
          this._target instanceof com.lineage.server.model.Instance.L1PetInstance) {
          if (obj instanceof L1PcInstance && (((L1PcInstance)obj).isGhost() || ((L1PcInstance)obj).isGmInvis()))
            continue; 
          if (!(obj instanceof com.lineage.server.model.Instance.L1SummonInstance) || !(obj instanceof com.lineage.server.model.Instance.L1PetInstance))
            continue; 
          targetList.put(Integer.valueOf(obj.getId()), Integer.valueOf(0));
          continue;
        } 
        if (!(obj instanceof com.lineage.server.model.Instance.L1MonsterInstance))
          continue; 
        targetList.put(Integer.valueOf(obj.getId()), Integer.valueOf(0));
      } 
    } else {
      targetList.put(Integer.valueOf(this._target.getId()), Integer.valueOf(0));
    } 
    if (targetList.size() == 0)
      return false; 
    Iterator<Integer> ite = targetList.keySet().iterator();
    while (ite.hasNext()) {
      int targetId = ((Integer)ite.next()).intValue();
      L1Object object = World.get().findObject(targetId);
      L1AttackMode attack = new L1AttackNpc(this._attacker, (L1Character)object);
      if (attack.calcHit()) {
        if (getMobSkillTemplate().getLeverage(idx) > 0)
          attack.setLeverage(getMobSkillTemplate().getLeverage(idx)); 
        attack.calcDamage();
      } 
      if (actId > 0)
        attack.setActId(actId); 
      if (targetId == this._target.getId()) {
        if (gfxId > 0)
          this._attacker.broadcastPacketAll((ServerBasePacket)new S_SkillSound(this._attacker.getId(), gfxId)); 
        attack.action();
      } 
      attack.commit();
    } 
    this._sleepTime = this._attacker.getAtkspeed();
    return true;
  }
  
  private boolean isSkillUseble(int skillIdx, boolean isTriRnd) {
    boolean useble = false;
    int type = getMobSkillTemplate().getType(skillIdx);
    int chance = RandomArrayList.getInc(100, 1);
    if (chance > getMobSkillTemplate().getTriggerRandom(skillIdx))
      return false; 
    if (isTriRnd || type == 3 || type == 4)
      useble = true; 
    if (getMobSkillTemplate().getTriggerHp(skillIdx) > 0) {
      int hpRatio = this._attacker.getCurrentHp() * 100 / this._attacker.getMaxHp();
      if (hpRatio > getMobSkillTemplate().getTriggerHp(skillIdx))
        return false; 
      useble = true;
    } 
    if (getMobSkillTemplate().getTriggerCompanionHp(skillIdx) > 0) {
      L1NpcInstance companionNpc = searchMinCompanionHp();
      if (companionNpc != null) {
        int hpRatio2 = companionNpc.getCurrentHp() * 100 / companionNpc.getMaxHp();
        if (hpRatio2 > getMobSkillTemplate().getTriggerCompanionHp(skillIdx))
          return false; 
        useble = true;
        this._target = (L1Character)companionNpc;
      } 
    } 
    if (getMobSkillTemplate().getTriggerRange(skillIdx) != 0) {
      if (this._attacker == null) {
        _log.info("MobSkill _attacker is null !!");
        return false;
      } 
      if (this._target == null) {
        _log.info("MobSkill _target is null !!");
        return false;
      } 
      int distance = this._attacker.getLocation().getTileLineDistance(this._target.getLocation());
      if (!getMobSkillTemplate().isTriggerDistance(skillIdx, distance))
        return false; 
      useble = true;
    } 
    if (getMobSkillTemplate().getTriggerCount(skillIdx) > 0) {
      if (getSkillUseCount(skillIdx) >= getMobSkillTemplate().getTriggerCount(skillIdx))
        return false; 
      useble = true;
    } 
    return useble;
  }
  
  private L1NpcInstance searchMinCompanionHp() {
    L1NpcInstance minHpNpc = null;
    int family = this._attacker.getNpcTemplate().get_family();
    Iterator<L1Object> iterator = World.get().getVisibleObjects((L1Object)this._attacker).iterator();
    while (iterator.hasNext()) {
      L1Object object = iterator.next();
      if (object instanceof L1NpcInstance) {
        L1NpcInstance npc = (L1NpcInstance)object;
        if (npc.getNpcTemplate().get_family() != family)
          continue; 
        minHpNpc = npc;
      } 
    } 
    return minHpNpc;
  }
  
  private L1Character changeTarget(int type, int idx) {
    L1NpcInstance l1NpcInstance;
    List<L1Character> targetList;
    Iterator<L1Object> iterator;
    L1Character target = null;
    switch (type) {
      case 2:
        return (L1Character)this._attacker;
      case 3:
        targetList = new ArrayList<>();
        iterator = World.get().getVisibleObjects((L1Object)this._attacker).iterator();
        while (iterator.hasNext()) {
          L1Object obj = iterator.next();
          if (obj instanceof L1PcInstance || obj instanceof com.lineage.server.model.Instance.L1PetInstance || obj instanceof com.lineage.server.model.Instance.L1SummonInstance || (
            this._attacker.getMapId() == 93 && obj instanceof com.lineage.server.model.Instance.L1MonsterInstance)) {
            L1Character cha = (L1Character)obj;
            int distance = this._attacker.getLocation().getTileLineDistance(cha.getLocation());
            if (!getMobSkillTemplate().isTriggerDistance(idx, distance))
              continue; 
            if (!this._attacker.glanceCheck(cha.getX(), cha.getY()))
              continue; 
            if (this._attacker.getMapId() != 93 && !this._attacker.getHateList().containsKey(cha))
              continue; 
            if (cha.isDead())
              continue; 
            if (cha instanceof L1PcInstance) {
              if (((L1PcInstance)cha).isGhost())
                continue; 
              if (((L1PcInstance)cha).isGmInvis())
                continue; 
            } 
            targetList.add((L1Character)obj);
          } 
        } 
        if (targetList.size() == 0) {
				target = _target;// 目前目标

			} else {// 目标清单不为0
				final int targetIndex = _rnd.nextInt(targetList.size());
				target = targetList.get(targetIndex);
			}
			break;

		default:
			target = _target;
			break;
		}
		return target;
  }
}
